package com.atguigu.yygh.hosp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.hosp.repository.ScheduleRepository;
import com.atguigu.yygh.hosp.service.HospitalService;
import com.atguigu.yygh.hosp.service.ScheduleService;
import com.atguigu.yygh.model.hosp.Hospital;
import com.atguigu.yygh.model.hosp.Schedule;
import com.atguigu.yygh.vo.hosp.BookingScheduleRuleVo;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:hx
 * @DateTime:2022/11/8 10:10
 * @Description:
 */
@Service
public class ScheduleServiceImpl implements ScheduleService {

    @Autowired
    private ScheduleRepository scheduleRepository;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private HospitalService hospitalService;

    @Override
    public void saveSchedule(Map<String, Object> paramMap) {
        Schedule schedule = JSONObject.parseObject(JSONObject.toJSONString(paramMap), Schedule.class);
        String hoscode = (String) paramMap.get("hoscode");
        String depcode = (String) paramMap.get("depcode");
        String hosScheduleId = (String) paramMap.get("hosScheduleId");
        Schedule mongoSchedule = scheduleRepository.getByHoscodeAndDepcodeAndHosScheduleId(hoscode, depcode,hosScheduleId);
        if (mongoSchedule == null){
            //添加
            schedule.setCreateTime(new Date());
            schedule.setUpdateTime(new Date());
            schedule.setIsDeleted(0);
            scheduleRepository.save(schedule);
        }else {
            //修改
            schedule.setCreateTime(mongoSchedule.getCreateTime());
            schedule.setUpdateTime(new Date());
            schedule.setIsDeleted(mongoSchedule.getIsDeleted());
            schedule.setId(mongoSchedule.getId());
            scheduleRepository.save(schedule);
        }
    }

    @Override
    public Page<Schedule> findSchedule(Map<String, Object> paramMap) {
        Integer pageNum = JSONObject.parseObject(JSONObject.toJSONString(paramMap.get("page")), Integer.class);
        Integer pageSize = JSONObject.parseObject(JSONObject.toJSONString(paramMap.get("limit")),Integer.class);
        String hoscode = JSONObject.parseObject(JSONObject.toJSONString(paramMap.get("hoscode")),String.class);
        Schedule schedule = new Schedule();
        schedule.setHoscode(hoscode);
        schedule.setIsDeleted(0);
        Example<Schedule> example = Example.of(schedule);
        Pageable pageable = PageRequest.of(pageNum,pageSize);
        Page<Schedule> all = scheduleRepository.findAll(example, pageable);
        return all;
    }

    @Override
    public void removeSchedule(Map<String, Object> paramMap) {
        String hoscode = (String) paramMap.get("hoscode");
        String hosScheduleId = (String) paramMap.get("hosScheduleId");
        Schedule schedule = new Schedule();
        schedule.setHoscode(hoscode);
        schedule.setHosScheduleId(hosScheduleId);
        scheduleRepository.delete(scheduleRepository.findOne(Example.of(schedule)).get());
    }

    @Override
    public Map<String, Object> getScheduleRule(Integer pageNum, Integer pageSize, String hoscode, String depcode) {
        Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode);
        Aggregation aggregation = Aggregation.newAggregation(
                //匹配查询
                Aggregation.match(criteria),
                //分组
                Aggregation.group("workDate").
                        first("workDate").as("workDate").
                        //统计该科室的就诊医生人数
                        count().as("docCount").
                        //统计可预约数
                        sum("reservedNumber").as("reservedNumber").
                        //统计剩余可预约数
                        sum("availableNumber").as("availableNumber"),
                //排序
                Aggregation.sort(Sort.Direction.ASC,"workDate"),
                //分页
                Aggregation.skip((pageNum - 1) * pageSize),
                Aggregation.limit(pageSize)
        );

        AggregationResults<BookingScheduleRuleVo> aggregate = mongoTemplate.aggregate(aggregation, Schedule.class, BookingScheduleRuleVo.class);
        List<BookingScheduleRuleVo> bookingScheduleRuleVoList = aggregate.getMappedResults();

        //查询总记录数
        Aggregation totalAgg = Aggregation.newAggregation(Aggregation.match(criteria),Aggregation.group("workDate"));
        AggregationResults<BookingScheduleRuleVo> totalAggs = mongoTemplate.aggregate(totalAgg, Schedule.class, BookingScheduleRuleVo.class);
        int total = totalAggs.getMappedResults().size();

        //获取日期对应的星期
        for (BookingScheduleRuleVo bookingScheduleRuleVo : bookingScheduleRuleVoList) {
            Date workDate = bookingScheduleRuleVo.getWorkDate();
            String dayOfWeek = this.getDayOfWeek(new DateTime(workDate));
            bookingScheduleRuleVo.setDayOfWeek(dayOfWeek);
        }

        //其他数据
        Hospital hospital = hospitalService.getByHoscode(hoscode);
        Map<String, String> baseMap = new HashMap<>();
        baseMap.put("hosname",hospital.getHosname());

        //返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("baseMap",baseMap);
        result.put("total",total);
        result.put("bookingScheduleRuleList",bookingScheduleRuleVoList);
        return result;
    }

    private String getDayOfWeek(DateTime dateTime) {
        String dayOfWeek = "";
        switch (dateTime.getDayOfWeek()) {
            case DateTimeConstants.SUNDAY:
                dayOfWeek = "周日";
                break;
            case DateTimeConstants.MONDAY:
                dayOfWeek = "周一";
                break;
            case DateTimeConstants.TUESDAY:
                dayOfWeek = "周二";
                break;
            case DateTimeConstants.WEDNESDAY:
                dayOfWeek = "周三";
                break;
            case DateTimeConstants.THURSDAY:
                dayOfWeek = "周四";
                break;
            case DateTimeConstants.FRIDAY:
                dayOfWeek = "周五";
                break;
            case DateTimeConstants.SATURDAY:
                dayOfWeek = "周六";
            default:
                break;
        }
        return dayOfWeek;
    }

    @Override
    public List<Schedule> getScheduleDetail(String hoscode, String depcode, String workDate) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Schedule schedule = new Schedule();
        schedule.setHoscode(hoscode);
        schedule.setDepcode(depcode);
        Date date = null;
        try {
            date = simpleDateFormat.parse(workDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        schedule.setWorkDate(date);
        Example<Schedule> example = Example.of(schedule);
        List<Schedule> scheduleList = scheduleRepository.findAll(example);
        return scheduleList;
    }

    @Override
    public void updateAvailableNumber(String scheduleId, Integer availableNumber) {
        Schedule schedule = scheduleRepository.findById(scheduleId).get();
        schedule.setAvailableNumber(availableNumber);
        scheduleRepository.save(schedule);
    }
}
